/*
 * MIT License
 *
 * Copyright (c) 2025 Mark·虎
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package com.hsxxherp.key.support.i18n.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hsxxherp.key.common.error.ErrorCode;
import com.hsxxherp.key.common.exception.BusinessException;
import com.hsxxherp.key.support.i18n.mapper.I18nLocaleMapper;
import com.hsxxherp.key.support.i18n.model.entity.I18nLocale;
import com.hsxxherp.key.support.i18n.service.II18nLocaleService;
import com.hsxxherp.key.support.model.entity.AdvancedQuery;
import com.hsxxherp.key.support.service.impl.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public  class I18nLocaleServiceImpl extends MPJBaseServiceImpl<I18nLocaleMapper, I18nLocale> implements II18nLocaleService {

    /**
     * 注册语种
     *
     * @param locale 语种信息
     * @return 注册后的语种信息
     */
    @Transactional
    @Override
    public I18nLocale registerLocale(I18nLocale locale) {
        // 分别检查语言代码和名称是否重复
        if (isLocaleCodeExists(locale.getLocaleCode(), null)) {
            throw new BusinessException("语言代码已存在，不能重复注册").setCode(ErrorCode.FAIL);
        }
        if (isLocaleNameExists(locale.getDescription(), null)) {
            throw new BusinessException("语言名称已存在，不能重复注册").setCode(ErrorCode.FAIL);
        }
        // 如果注册的语种为默认语种，将其他未删除的语种设置为非默认
        if (locale.getIsDefault() != null && locale.getIsDefault()) {
            clearOtherDefaultLocales(locale.getId());
        }
        baseMapper.insert(locale);

        // 按照模板发布资源



        return locale;
    }

    /**
     * 获取所有语种
     *
     * @return 语种列表
     */
    @Override
    public List<I18nLocale> getAllLocales() {
        return baseMapper.selectList(null);
    }

    /**
     * 更新语种信息
     *
     * @param locale 语种信息
     * @return 更新结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public I18nLocale updateLocale(I18nLocale locale) {
        // 检查传入的语种信息是否为空
        if (locale == null) {
            throw new BusinessException("更新的语种信息不能为空").setCode(ErrorCode.FAIL);
        }
        // 检查语种 ID 是否为空
        if (StringUtils.isEmpty(locale.getId())) {
            throw new BusinessException("更新的语种 ID 不能为空").setCode(ErrorCode.FAIL);
        }
        // 分别检查语言代码和名称是否重复，排除当前语种
        if (isLocaleCodeExists(locale.getLocaleCode(), locale.getId())) {
            throw new BusinessException("语言代码已存在，不能重复更新").setCode(ErrorCode.FAIL);
        }
        if (isLocaleNameExists(locale.getDescription(), locale.getId())) {
            throw new BusinessException("语言名称已存在，不能重复更新").setCode(ErrorCode.FAIL);
        }
        // 如果更新为默认语种，将其他未删除的语种设置为非默认
        if (locale.getIsDefault() != null && locale.getIsDefault()) {
            clearOtherDefaultLocales(locale.getId());
        }
        // 尝试更新语种信息
        if (updateById(locale)) {
            return getById(locale.getId());
        } else {
            throw new BusinessException("更新语种信息失败").setCode(ErrorCode.FAIL);
        }
    }

    /**
     * 删除语种
     *
     * @param id 语种 ID
     * @return 删除结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteLocale(String id) {
        I18nLocale locale = getById(id);
        if (locale != null && locale.getIsDefault() != null && locale.getIsDefault()) {
            // 如果删除的是默认语种，从剩余未删除的语种中选一个设为默认
            setNewDefaultLocale(id);
        }
        return removeById(id);
    }

    @Override
    public List<I18nLocale> advancedQueryI18nLocales(AdvancedQuery query) {
        return selectJoinList(query);
    }

    /**
     * 将其他未删除的语种设置为非默认
     *
     * @param currentLocaleId 当前语种 ID
     */
    private void clearOtherDefaultLocales(String currentLocaleId) {
        baseMapper.update(null,
                new UpdateWrapper<I18nLocale>()
                        .set("is_default", false)
                        .ne("id", currentLocaleId)
                        .eq("deleted", false));
    }

    /**
     * 当删除默认语种时，从剩余未删除的语种中选一个设为默认
     *
     * @param deletedLocaleId 被删除的语种 ID
     */
    private void setNewDefaultLocale(String deletedLocaleId) {
        I18nLocale newDefaultLocale = baseMapper.selectOne(
                new QueryWrapper<I18nLocale>()
                        .ne("id", deletedLocaleId)
                        .eq("deleted", false)
                        .last("LIMIT 1"));
        if (newDefaultLocale != null) {
            newDefaultLocale.setIsDefault(true);
            updateById(newDefaultLocale);
        }
    }

    /**
     * 检查语言代码是否已存在
     *
     * @param localeCode 语言代码
     * @param excludeId  排除的 ID（更新时使用）
     * @return 是否存在
     */
    private boolean isLocaleCodeExists(String localeCode, String excludeId) {
        QueryWrapper<I18nLocale> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("locale_code", localeCode);
        if (StringUtils.hasText(excludeId)) {
            queryWrapper.ne("id", excludeId);
        }
        return count(queryWrapper) > 0;
    }

    /**
     * 检查语言名称是否已存在
     *
     * @param description 语言名称
     * @param excludeId   排除的 ID（更新时使用）
     * @return 是否存在
     */
    private boolean isLocaleNameExists(String description, String excludeId) {
        QueryWrapper<I18nLocale> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("description", description);
        if (StringUtils.hasText(excludeId)) {
            queryWrapper.ne("id", excludeId);
        }
        return count(queryWrapper) > 0;
    }
}